package com.jl.rule;

import com.jl.JLDataTime;
import lombok.SneakyThrows;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Date;

/**
 * 规则 日期匹对
 */
public class JLRuleDateTimeEqs<T extends Comparable<?>> implements PreciseShardingAlgorithm<T>, RangeShardingAlgorithm<T> {

    /**
     * 格式，支持年月 yyyy_mm
     */
    private String form;

    /**
     * 切片月数，支持一年内，且能被12整除
     */
    private String mnum;

    public JLRuleDateTimeEqs(String form) {
        String[] split = form.split(":");
        this.mnum = split[1];
        this.form = split[0];
    }

    @Override
    public String doSharding(Collection<String> collection, PreciseShardingValue<T> preciseShardingValue) {
        T v = preciseShardingValue.getValue();
        String value = v instanceof LocalDateTime ? JLDataTime.toString((LocalDateTime) v)
                : v instanceof Date || v instanceof Integer || v instanceof Long ? new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(v)
                : v instanceof String ? (String) v
                : null;
        String handle = handle(value);
        for (String each : collection) {
            if (each.endsWith(handle)) {
                return each;
            }
        }
        return null;
    }

    @Override
    public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<T> rangeShardingValue) {
        return collection;
    }

    @SneakyThrows
    private String handle(String time) {
        String y = time.substring(0, 4);
        String m = time.substring(5, 7);
        if (mnum.equals("2") || mnum.equals("02")) {
            if (Integer.parseInt(m) % 2 != 0) {
                int v = Integer.parseInt(m) + 1;
                m = String.valueOf(v < 10 ? "0" + v : v);
            }
        } else if (mnum.equals("3") || mnum.equals("03")) {
            int ms = Integer.parseInt(m);
            m = ms <= 3 ? "03"
                    : ms <= 6 ? "06"
                    : ms <= 9 ? "09"
                    : ms <= 12 ? "12"
                    : null;
        } else if (mnum.equals("4") || mnum.equals("04")) {
            int ms = Integer.parseInt(m);
            m = ms <= 4 ? "04"
                    : ms <= 8 ? "08"
                    : ms <= 12 ? "12"
                    : null;
        } else if (mnum.equals("6") || mnum.equals("06")) {
            int ms = Integer.parseInt(m);
            m = ms <= 6 ? "06"
                    : ms <= 12 ? "12"
                    : null;
        } else if (mnum.equals("12")) {
            form = "yyyy";
        }
        Date parse = new SimpleDateFormat("yyyy-MM").parse(y + "-" + m);
        return new SimpleDateFormat(form).format(parse);
    }
}
